<?php

namespace app\admin\controller\dts\point\task;

use app\admin\model\dts\point\task\Log;
use app\common\controller\Backend;
use think\Db;

/**
 * 巡检任务管理
 *
 * @icon fa fa-circle-o
 */
class Task extends Backend
{

    /**
     * Task模型对象
     * @var \app\admin\model\dts\point\Task
     */
    protected $model = null;

    public function _initialize()
    {
        parent::_initialize();
        $this->model = new \app\admin\model\dts\point\Task;

    }



    /**
     * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
     * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
     * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
     */

    public function index() {
        //当前是否为关联查询
        $this->relationSearch = true;
        //设置过滤方法
        $this->request->filter(['strip_tags', 'trim']);
        if ($this->request->isAjax()) {
            //如果发送的来源是Selectpage，则转发到Selectpage
            if ($this->request->request('keyField')) {
                return $this->selectpage();
            }
            list($where, $sort, $order, $offset, $limit) = $this->buildparams();

            $list = Db::name('dts_point_task')->alias('task')
            ->field('task.*,GROUP_CONCAT(DISTINCT grouping.name) as grouping__names,time.name as time__name,admin.nickname as admin__nickname')
            ->join([
                ['dts_point_grouping grouping', 'FIND_IN_SET(grouping.id,task.point_grouping_ids)', 'left'],
                ['dts_point_time time', 'time.id = task.point_time_id', 'left'],
                ['admin admin', 'admin.id = task.admin_id', 'left']
            ])
            ->where($where)
            ->order($sort, $order)
            ->group('task.id')
            ->paginate($limit);

            $result = array("total" => $list->total(), "rows" => paginateList($list));

            return json($result);
        }

        return $this->view->fetch();
    }

    protected function before_add($params)
    {
        $idArr = array_unique(explode(',', $params['point_grouping_ids']));
        foreach($idArr as $id) {
            $num = Db::name('dts_point_task')->whereRaw('FIND_IN_SET('.$id.',point_grouping_ids) > 0 and point_time_id = '.$params['point_time_id'])->count(1);
            if($num) {
                ajaxerror('任务已有点位库{'.$id.'}');
            }
        }
        return $params;
    }

    protected function after_add($newid, $params)
    {
        $idArr = array_unique(explode(',', $params['point_grouping_ids']));
        Db::name('dts_point_grouping')->where('id', 'in', $idArr)->update(['status' => 1]);

        $this->calculation($newid, $params);
    }

    protected function before_edit($params, $changeData, $originData)
    {

        if(isset($changeData['point_grouping_ids']) || isset($changeData['point_time_id'])) {
            $idArr = array_unique(explode(',', $params['point_grouping_ids']));
            foreach($idArr as $id) {
                $num = Db::name('dts_point_task')->whereRaw('FIND_IN_SET('.$id.',point_grouping_ids) > 0 and point_time_id = '.$params['point_time_id'])->count(1);
                if($num > 1) {
                    ajaxerror('任务已有点位库{'.$id.'}');
                }
            }

            $this->calculation($originData['id'], $params, 1);
        }

        if(isset($changeData['point_grouping_ids'])) {
            $idArr1 = array_unique(explode(',', $params['point_grouping_ids']));
            $idArr2 = array_unique(explode(',', $originData['point_grouping_ids']));
            $size1 = sizeof($idArr1);
            $size2 = sizeof($idArr2);

            if($size1 >= $size2) {
                $idArr = array_diff($idArr1, $idArr2);
                $update = ['status' => 1];
            }else {
                $idArr = array_diff($idArr2, $idArr1);
                $update = ['status' => 0];
            }

            Db::name('dts_point_grouping')->where('id', 'in', $idArr)->update($update);
        }

        if(isset($changeData['admin_id'])) {
            Db::name('dts_point_task_log')->where(['point_task_id' => $originData['id'], 'status' => ['<>', Log::STATUS_2]])->update(['admin_id' => $params['admin_id']]);
        }
        
        return $params;
    }

    /**
     * $timeId 时间段Id
     * $taskId 任务Id
     * $type   0=增加 1=修改
     */
    public function calculation($taskId, $params, $type = 0) {
        //当前时间
        $currtime = strtotime(date('Y-m-d H:i:s', time()));
        $dayofhour = date('H', $currtime);
        $dayofweek = date('w', $currtime); 
        $currweek = date('W', $currtime); 
        $currday = date('d', $currtime);

        if($type) {//删除未开始和巡检中执行任务
            $query = ['point_task_id' => $taskId, 'status' => ['in', [Log::STATUS_1, Log::STATUS_2]]];
            $num = Db::name('dts_point_task_log')->where($query)->count(1);
            if($num) {
                ajaxerror('有巡检中或超时任务，不能变更点位库或时间段');
            }
            Db::name('dts_point_task_log')->where(['point_task_id' => $taskId, 'status' => Log::STATUS_0])->delete();
        }

        //查询时间段
        $items = Db::name('dts_point_time')->where('id', $params['point_time_id'])->find();
        
        $data = [];
        $idArr = array_unique(explode(',', $params['point_grouping_ids']));
        foreach($idArr as $id) {
            $data[] = ['point_grouping_id' => $id, 'point_task_id' => $taskId, 'admin_id' => $params['admin_id'], 'nottime' => date('Y-m-d', time()), 'startperiod' => $items['startperiod'], 'endperiod' => $items['endperiod']];
        }
        $taskLogModel = new \app\admin\model\dts\point\task\Log;

        switch($items['type']) {//创建执行任务
            case 'not':
                $nottimeS = strtotime($items['nottime'].' '.$items['startperiod']);
                $nottimeE = strtotime($items['nottime'].' '.$items['endperiod']);
                if($currtime < $nottimeS) {
                    $taskLogModel->saveAll($data);
                }
                if($currtime >= $nottimeS && $currtime <= $nottimeE) {
                    $data = $this->addData($data, Log::STATUS_1);
                    $taskLogModel->saveAll($data);
                }
                if($currtime > $nottimeE) {
                    $data = $this->addData($data, Log::STATUS_2);
                    $taskLogModel->saveAll($data);
                }
                break;
            case 'day':
                list($hourS, $minuteS, $secondS) = array_map('intval', explode(':', $items['startperiod']));
                list($hourE, $minuteE, $secondE) = array_map('intval', explode(':', $items['endperiod']));
                if($dayofhour < $hourS) {
                    $taskLogModel->saveAll($data);
                }
                if($dayofhour >= $hourS && $dayofhour <= $hourE) {
                    $data = $this->addData($data, Log::STATUS_1);
                    $taskLogModel->saveAll($data);
                }
                if($dayofhour > $hourE) {
                    $data = $this->addData($data, Log::STATUS_2);
                    $taskLogModel->saveAll($data);
                }
                break;
            case 'week':
                list($hourS, $minuteS, $secondS) = array_map('intval', explode(':', $items['startperiod']));
                list($hourE, $minuteE, $secondE) = array_map('intval', explode(':', $items['endperiod']));
                $itemArr = explode(',', $items['weekarr']);
                if(in_array($dayofweek, $itemArr) && $dayofhour <= $hourS) {
                    $taskLogModel->saveAll($data);
                }
                if(in_array($dayofweek, $itemArr) && ($dayofhour > $hourS && $dayofhour < $hourE)) {
                    $data = $this->addData($data, Log::STATUS_1);
                    $taskLogModel->saveAll($data);
                }
                if(in_array($dayofweek, $itemArr) && ($dayofhour > $hourE)) {
                    $data = $this->addData($data, Log::STATUS_2);
                    $taskLogModel->saveAll($data);
                }
                break;
            case 'toweek':
                list($hourS, $minuteS, $secondS) = array_map('intval', explode(':', $items['startperiod']));
                list($hourE, $minuteE, $secondE) = array_map('intval', explode(':', $items['endperiod']));
                $itemArr = explode(',', $items['weekarr']);
                if(in_array($dayofweek, $itemArr)) {
                    if(($currweek % 2) == 0 && $items['is_even'] == 0 && ($dayofhour <= $hourS)) {//偶数周
                        $taskLogModel->saveAll($data);
                    }
                    if(($currweek % 2) == 0 && $items['is_even'] == 0 && ($dayofhour > $hourS && $dayofhour < $hourE)) {//偶数周
                        $data = $this->addData($data, Log::STATUS_1);
                        $taskLogModel->saveAll($data);
                    }
                    if(($currweek % 2) == 0 && $items['is_even'] == 0 && ($dayofhour > $hourE)) {//偶数周
                        $data = $this->addData($data, Log::STATUS_2);
                        $taskLogModel->saveAll($data);
                    }
                    if(($currweek % 2) != 0 && $items['is_even'] != 0 && ($dayofhour <= $hourS)) {//单数周
                        $taskLogModel->saveAll($data);
                    }
                    if(($currweek % 2) != 0 && $items['is_even'] != 0 && ($dayofhour > $hourS && $dayofhour < $hourE)) {//单数周
                        $data = $this->addData($data, Log::STATUS_1);
                        $taskLogModel->saveAll($data);
                    }
                    if(($currweek % 2) != 0 && $items['is_even'] != 0 && ($dayofhour > $hourE)) {//单数周
                        $data = $this->addData($data, Log::STATUS_2);
                        $taskLogModel->saveAll($data);
                    }
                }
                break;
            case 'month':
                list($hourS, $minuteS, $secondS) = array_map('intval', explode(':', $items['startperiod']));
                list($hourE, $minuteE, $secondE) = array_map('intval', explode(':', $items['endperiod']));
                $itemArr = explode(',', $items['months']);
                if(in_array($currday, $itemArr)) {
                    if($dayofhour < $hourS) {
                        $taskLogModel->saveAll($data);
                    }
                    if($dayofhour >= $hourS && $dayofhour <= $hourE) {
                        $data = $this->addData($data, Log::STATUS_1);
                        $taskLogModel->saveAll($data);
                    }
                    if($dayofhour > $hourE) {
                        $data = $this->addData($data, Log::STATUS_2);
                        $taskLogModel->saveAll($data);
                    }
                }
                break;        
        }
    }

    public function addData($data, $status) {
        foreach($data as $key => $item) {
            $data[$key]['status'] = $status;
        }

        return $data;
    }

    protected function after_del($v)
    {
        $ids = explode(',', $v['point_grouping_ids']);
        \app\admin\model\dts\point\Grouping::where('id', 'in', $ids)->update(['status' => 0]);
        \app\admin\model\dts\point\task\Log::where(['point_task_id' => $v['id'], 'status' => ['<>', Log::STATUS_3]])->delete();
    }
}
